使用拖放操纵器

使用拖放操纵器可以使用户在 Kanzi 应用程序中拖放节点。请参阅 启用节点的拖放手势

使用 拖放操纵器 (Drag and Drop Manipulator) 触发器响应拖放手势。例如,您可以设置用户拖放节点时的节点外观。请参阅 使用拖放操纵器 (Drag and Drop Manipulator) 触发器

拖放操纵器是一种输入操纵器,您可以用于在 Kanzi 应用程序中添加手势识别到节点上。您可以通过 Kanzi Engine API 分配输入操纵器。请参阅使用输入操纵器

通过完成教程学习如何使用拖放操纵器。请参阅 教程:拖放

启用节点的拖放手势

要启用节点的拖放手势:

  1. Kanzi Studio 中使用应用程序 (Application) 模板创建工程。
  2. 工程 (Project) 中创建要启用拖放手势的节点。
    例如,创建一个2D 空节点 (Empty Node 2D) 节点并将其命名为 DragAndDropNode
  3. 工程 (Project) 中选择您在上一步中创建的节点,在属性 (Properties) 中添加可测试命中 (Hit Testable) 属性,并将其设置为启用。
    当您启用属性时,用户能选取节点。
    默认情况下,按钮 (Button)列表框项容器 (List Box Item Container)滚动视图 (Scroll View)滑块 (Slider) 节点启用命中测试。 请参阅定义哪个节点接收用户输入
  4. 工程 (Project)按下 Alt 并右键点击 您创建的节点并选择别名 (Alias)
    Kanzi Studio 会创建一个别名(它指向您从中创建该别名的节点),并将该别名添加到它的含资源字典的最近祖先节点的资源字典中。
    使用 # 符号后跟别名名称访问别名目标节点。
  5. 选择文件 (File) > 导出 (Export) > 导出 KZB (Export KZB)
    Kanzi StudioKanzi Studio 工程创建 kzb 文件和配置文件。Kanzi Studio 将导出的文件存储在 <ProjectName>/Application/bin 目录或您在 工程 (Project) > 属性 (Properties)二进制导出目录 (Binary Export Directory) 属性中指定的位置。Kzb 文件包含 Kanzi Studio 工程中的所有节点和资源,您在本地化表中标记为本地化包的资源除外。
    当您从 Visual Studio 中运行您的 Kanzi 应用程序时,您的应用程序就会加载 kzb 文件和配置文件。
  6. 在 Visual Studio 中打开存储在 <ProjectName>/Application/configs/platforms/win32 中的解决方案,并在实现应用程序逻辑的文件中创建并配置拖放操纵器:
    1. 为拖放消息定义处理程序。
      例如,在实现应用程序逻辑的类的 public 部分后添加:
      private: 
      
          // 定义 2D 节点的 DragAndDropManipulator::StartedMessage 消息处理程序 
          //这些节点带有生成拖放消息的输入操纵器。
          //这样可为拖动准备 2D 节点。
          void onDragStarted(DragAndDropManipulator::StartedMessageArguments& messageArguments)
          {
              //从消息参数获得用户拖动的节点。
              Node2DSharedPtr dragAndDropNode = dynamic_pointer_cast<Node2D>(messageArguments.getSource());
      
              if (!dragAndDropNode)
              {
                  return;
              }
      
              //保存用户相对于节点原点(默认情况下为左上角)
              //开始拖动节点的起点。
              m_dragGrabOffset = messageArguments.getPoint();
      
              //在节点上开始拖放手势时,让节点位于前面。
              dragAndDropNode->moveToFront();
          }
      
          //定义 2D 节点的 DragAndDropManipulator::MovedMessage 消息处理程序 
          //这些节点带有生成拖放消息的输入操纵器。
          //这样可按用户拖动的距离变换(移动)节点。
          void onDragMoved(DragAndDropManipulator::MovedMessageArguments& messageArguments)
          {
              //从消息参数获得用户拖动的节点。
              Node2DSharedPtr dragAndDropNode = dynamic_pointer_cast<Node2D>(messageArguments.getSource());
      
              if (!dragAndDropNode)
              {
                  return;
              }
      
              //相对于节点原点移动 getPoint 提供的行程距离。
              //要保持从节点上相同的点开始拖动,减去抓取偏移。
              SRTValue2D transform = dragAndDropNode->getLayoutTransformation();
              transform.translate(messageArguments.getPoint() - m_dragGrabOffset);
              dragAndDropNode->setLayoutTransformation(transform);
          }
      
          //从用户按下或点击的 DragAndDropNode 左上角偏移。
          Vector2 m_dragGrabOffset;
    2. onProjectLoaded() 函数中创建 DragAndDropManipulator 并订阅其消息。
      例如,添加:
          virtual void onProjectLoaded() KZ_OVERRIDE
          {
              ScreenSharedPtr screen = getScreen();
              Domain* domain = getDomain();
      
              //使用别名获取DragAndDropNode。
              NodeSharedPtr dragAndDropNode = screen->lookupNode<Node>("#DragAndDropNode");
      
              //创建生成拖放消息的输入操纵器。
              DragAndDropManipulatorSharedPtr nodeDragAndDropManipulator = DragAndDropManipulator::create(domain);
      
              //添加输入操纵器到 DragAndDropNode。
              dragAndDropNode->addInputManipulator(nodeDragAndDropManipulator);
      
              //在拖放开始前设置长按持续时间为 200 ms。默认值为 500 ms。
              //这是用户在开始拖动节点前需按下节点的时间。
              nodeDragAndDropManipulator->setPressDuration(chrono::milliseconds(200));
      
              //订阅 DragAndDropNode 节点的 DragAndDropManipulator::StartedMessage 消息。
              //DragAndDropManipulator 在用户按下该节点
              //获取 DragAndDropManipulator::setPressDuration 设置的持续时间时生成此消息。
              dragAndDropNode->addMessageHandler(DragAndDropManipulator::StartedMessage, bind(&MyProject::onDragStarted, this, placeholders::_1));
      
              //订阅 DragAndDropNode 节点的 DragAndDropManipulator::MovedMessage 消息。
              // DragAndDropManipulator 在手指或鼠标移动时生成此消息。
              dragAndDropNode->addMessageHandler(DragAndDropManipulator::MovedMessage, bind(&MyProject::onDragMoved, this, placeholders::_1));
          }
  7. 构建和运行应用程序。 请参阅部署 Kanzi 应用程序
    在应用程序中长按并拖动启用拖放手势的节点。

使用拖放操纵器 (Drag and Drop Manipulator) 触发器

使用 拖放操纵器 (Drag and Drop Manipulator) 触发器响应拖放手势。例如,您可以设置用户拖放节点时的节点外观。

拖放操纵器 (Drag and Drop Manipulator) 有这些触发器:

要使用拖放操纵器 (Drag and Drop Manipulator) 触发器:

  1. 启用节点的拖放手势。请参阅 启用节点的拖放手势
  2. 定义您想通过拖放操纵器 (Drag and Drop Manipulator) 触发器设置的行为。
    例如,创建状态机,您可以定义状态以设置节点在拖放已开始 (Drag and Drop Started)拖放已移动 (Drag and Drop Moved)拖放已完成 (Drag and Drop Finished) 触发器被触发时的外观。请参阅 创建状态机
  3. 添加和配置拖放操纵器 (Drag and Drop Manipulator) 触发器:
    1. 工程 (Project) 中,选择要为其添加触发器的节点,并在节点组件 (Node Components) > 触发器 (Triggers) 部分添加其中一个拖放操纵器 (Drag and Drop Manipulator) 触发器。
      例如,在工程 (Project) 中选择启用拖放手势的节点,并在节点组件 (Node Components) 中添加拖放已开始 (Drag and Drop Started) 触发器。
    2. 在您在上一步创建的触发器中,点击 触发器设置 (Trigger Settings) 并在 触发器设置编辑器 (Trigger Settings Editor) 中禁用 设置已处理消息 (Set Message Handled) 属性。
      当您禁用 设置已处理消息 (Set Message Handled) 属性,此触发器拦截消息,但不会停止消息。这样您可以让输入操纵器处理该消息。
    3. 在您创建的触发器中,选择 添加 (Add) 下拉菜单中的动作,并配置该动作。
      例如,选择转到状态 (Go to State) 动作并在动作设置中设置:
      • 项 (Item) 设为启用拖放手势的节点
      • 状态 (State) 设为设置节点在拖放已开始 (Drag and Drop Started) 触发器被触发时的外观的状态
  4. 重复上一步,以添加并配置更多拖放操纵器 (Drag and Drop Manipulator) 触发器。
    例如,添加拖放已移动 (Drag and Drop Moved)拖放已完成 (Drag and Drop Finished) 触发器。在每个触发器的转到状态 (Go to State) 动作中,将状态 (State) 设置为将在触发器被触发时会设置节点外观的状态。
  5. 选择文件 (File) > 导出 (Export) > 导出 KZB (Export KZB)
  6. 构建和运行应用程序。 请参阅部署 Kanzi 应用程序
    在应用程序中长按并拖动启用拖放手势的节点。

在 API 中使用拖放操纵器

有关详细信息,请参阅 API reference 中的 DragAndDropManipulator 类。

另请参阅

教程:拖放

处理用户输入

部署 Kanzi 应用程序

使用触发器